package top.dingwen.io.treasure.websocket.core.interceptor;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.server.HandshakeInterceptor;
import top.dingwen.io.treasure.base.constant.SupWarsConstant;
import top.dingwen.io.treasure.base.user.CurrentUserHelper;
import top.dingwen.io.treasure.base.util.str.StringPlusUtils;
import top.dingwen.io.treasure.webplus.util.servlet.ServletUtils;
import top.dingwen.io.treasure.websocket.autoconfigure.WebSocketProperties;
import top.dingwen.io.treasure.websocket.constant.WebSocketConstant;

import javax.annotation.Resource;
import java.util.Map;
import java.util.Objects;


/**
 * WebSocket握手请求的拦截器
 *
 * @author dingwen
 * @since 2024/10/16
 */
@Slf4j
@Component
@SuppressWarnings(SupWarsConstant.ALL)
public class WebSocketInterceptor implements HandshakeInterceptor {

    @Resource
    private WebSocketProperties websocketProperties;

    /**
     * WebSocket握手之前执行的前置处理方法
     *
     * @param request    WebSocket握手请求
     * @param response   WebSocket握手响应
     * @param wsHandler  WebSocket处理程序
     * @param attributes 与WebSocket会话关联的属性
     * @return 如果允许握手继续进行，则返回true；否则返回false
     */
    @Override
    public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler
            , Map<String, Object> attributes) {
        try {
            // 检查是否登录,是否有权限
            Object loginId = CurrentUserHelper.getLoginId();
            String loginName = CurrentUserHelper.getLoginName();
            if (Convert.toBool(websocketProperties.getAuth(), true) &&
                    (ObjectUtil.isNull(loginId) || StrUtil.isBlank(loginName))) {
                log.info("{},{},WebSocket 认证失败,无法访问系统资源", WebSocketConstant.WS_L_O_S, WebSocketConstant.WS_L_H);
                return false;
            }
            if (Objects.nonNull(attributes)) {
                attributes.put(WebSocketConstant.LOGIN_ID_KEY, CurrentUserHelper.getLoginId());
                attributes.put(WebSocketConstant.LOGIN_NAME_KEY, CurrentUserHelper.getLoginName());
                attributes.put(WebSocketConstant.SEND_LOGIN_ID_KEY,
                        ServletUtils.getParameter(WebSocketConstant.SEND_LOGIN_ID_KEY,
                                StringPlusUtils.EMPTY)
                );
            }
            return true;
        } catch (Exception e) {
            log.error("{},{},WebSocket 认证失败,无法访问系统资源,消息:[{}]",
                    WebSocketConstant.WS_L_O_S, WebSocketConstant.WS_L_H,
                    e.getMessage());
            return false;
        }
    }

    /**
     * WebSocket握手成功后执行的后置处理方法
     *
     * @param request   WebSocket握手请求
     * @param response  WebSocket握手响应
     * @param wsHandler WebSocket处理程序
     * @param exception 握手过程中可能出现的异常
     */
    @Override
    public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler,
                               Exception exception) {
        // 在这个方法中可以执行一些握手成功后的后续处理逻辑，比如记录日志或者其他操作
    }

}
